import tkinter as tk
from tkinter import ttk, messagebox
import customtkinter
from ui.pages.scrollable_page import ScrollablePage
from core.utils.image_utils import load_thumbnail
from core.services.data_manager import DataManager
from core.utils.error_handler import ErrorHandler, safe_json_save
from core.utils.logger import error, warning, debug, info
from core.utils.i18n import t
from core.utils.ui_optimizer import load_image_async
from core.models.order import Order, OrderItem, OrderStatus
from ui.styles.theme import Theme
import json
import os
import uuid
from datetime import datetime

class CartPage(ScrollablePage):
    """Cart page with receipt dialog on checkout."""

    def create_widgets(self):
        content = self.scrollable_frame

        # 获取主题颜色
        fg_primary = Theme.get_color('fg_primary')
        fg_tertiary = Theme.get_color('fg_tertiary')
        accent_color = Theme.get_color('accent')

        header = customtkinter.CTkFrame(content, fg_color="transparent")
        header.pack(fill='x', padx=8)
        back_btn = customtkinter.CTkButton(
            header, 
            text=t('cart.back'),
            width=80,
            command=lambda: self.controller.show_page('ProductPage')
        )
        back_btn.pack(side='left', padx=(0, 8))
        title = customtkinter.CTkLabel(
            header, 
            text=t('cart.title'), 
            font=('Arial', 18, 'bold'),
            text_color=fg_primary
        )
        title.pack(side='left')
        
        # 全选复选框
        select_all_frame = customtkinter.CTkFrame(content, fg_color="transparent")
        select_all_frame.pack(fill='x', padx=20, pady=(5, 0))
        self.select_all_var = tk.BooleanVar(value=True)
        self.select_all_cb = customtkinter.CTkCheckBox(
            select_all_frame,
            text=t('cart.select_all'),
            variable=self.select_all_var,
            command=self._toggle_select_all
        )
        self.select_all_cb.pack(side='left')

        self.items_container = ttk.Frame(content)
        self.items_container.pack(fill='both', expand=True, padx=12)

        footer = customtkinter.CTkFrame(content, fg_color="transparent")
        footer.pack(fill='x', padx=12, pady=12)
        self.total_label = customtkinter.CTkLabel(
            footer, 
            text=t('cart.total', total=0.0), 
            font=('Arial', 12, 'bold'),
            text_color=fg_primary
        )
        self.total_label.pack(side='right')
        self.checkout_btn = customtkinter.CTkButton(
            footer, 
            text=t('cart.checkout_selected'), 
            command=self._checkout,
            width=120
        )
        self.checkout_btn.pack(side='right', padx=12)
        
        # 用于跟踪选中状态
        self.selected_items = {}  # {product_id: BooleanVar}

    def _render_item(self, parent, cart_item):
        # 使用纯 ttk 组件，保持与 ScrollableFrame 的兼容性
        frame = ttk.Frame(parent)
        frame.pack(fill='x', pady=6, padx=5)
        
        # 内部容器用于布局
        inner = ttk.Frame(frame)
        inner.pack(fill='both', expand=True, padx=8, pady=8)
        
        # 复选框
        checkbox_var = tk.BooleanVar(value=True)
        self.selected_items[cart_item.product.product_id] = checkbox_var
        
        def on_checkbox_change():
            self._update_total()
            # 更新全选状态
            all_selected = all(var.get() for var in self.selected_items.values())
            self.select_all_var.set(all_selected)
        
        checkbox = ttk.Checkbutton(
            inner,
            variable=checkbox_var,
            command=on_checkbox_change
        )
        checkbox.pack(side='left', padx=(0, 8))

        # 缩略图 (very small thumbnail)
        thumb = tk.Label(inner, width=48, height=48)
        thumb.pack(side='left')
        # 异步加载商品图片
        img_path = getattr(cart_item.product, 'image_path', None)
        if img_path:
            def on_image_loaded(img, error):
                if img and not error:
                    thumb.config(image=img, text='')
                    thumb.image = img
                else:
                    if error:
                        warning(f"加载商品图片失败: {str(error)}")
                    thumb.config(text='No Image', fg='#999')
            
            load_image_async(frame, img_path, (48, 48), on_image_loaded)
        else:
            thumb.config(text='No Image', fg='#999')

        # 商品详情 - 使用英文名称
        details = ttk.Frame(inner)
        details.pack(side='left', fill='x', expand=True, padx=12)
        product_name = cart_item.product.get_display_name() if hasattr(cart_item.product, 'get_display_name') else (getattr(cart_item.product, 'name_en', None) or cart_item.product.name)
        ttk.Label(details, text=product_name, font=('Arial', 12, 'bold')).pack(anchor='w')
        
        category = getattr(cart_item.product, 'get_category', None)
        if callable(category):
            cat_text = category()
        else:
            cat_text = getattr(cart_item.product, 'category', '')
        ttk.Label(details, text=t('cart.category_label', category=cat_text), foreground='#666').pack(anchor='w')
        ttk.Label(details, text=f"{t('cart.item.description')}: {getattr(cart_item.product, 'description', '')}", 
                 foreground='#555', wraplength=360).pack(anchor='w')

        # 右侧：价格和操作
        right = ttk.Frame(inner)
        right.pack(side='right')
        
        price_label = ttk.Label(
            right, 
            text=t('product.product_detail.price', price=cart_item.product.price), 
            font=('Arial', 12, 'bold'),
            foreground='#FF6B35'
        )
        price_label.pack(anchor='e')

        # 小计标签
        subtotal_lbl = ttk.Label(
            right, 
            text=t('cart.item.subtotal', subtotal=cart_item.subtotal),
            foreground='#666'
        )
        subtotal_lbl.pack(anchor='e', pady=(4, 6))

        # 数量控制
        qfrm = ttk.Frame(right)
        qfrm.pack(anchor='e', pady=(6, 4))
        
        customtkinter.CTkLabel(qfrm, text=t('cart.qty')).pack(side='left', padx=(0, 6))

        qty_val = tk.IntVar(value=cart_item.quantity)
        qty_label_ref = {'label': None}  # 用于存储 label 引用

        def decrease():
            val = max(1, qty_val.get() - 1)
            qty_val.set(val)
            if qty_label_ref['label']:
                qty_label_ref['label'].configure(text=str(val))
            self.controller.shopping_cart.update_quantity(cart_item.product.product_id, val)
            subtotal_lbl.configure(text=f'Subtotal: ¥{next((it.subtotal for it in self.controller.shopping_cart.items if it.product.product_id==cart_item.product.product_id), 0):.2f}')
            self._update_total()
            try:
                product_page = self.controller.pages.get('ProductPage')
                if product_page and hasattr(product_page, 'update_cart_display'):
                    product_page.update_cart_display()
            except AttributeError as e:
                debug(f"ProductPage没有update_cart_display方法: {str(e)}")
            except Exception as e:
                ErrorHandler.log_exception(e, "更新商品页面购物车显示")

        def increase():
            try:
                val = qty_val.get() + 1
                self.controller.shopping_cart.update_quantity(cart_item.product.product_id, val)
                qty_val.set(val)
                if qty_label_ref['label']:
                    qty_label_ref['label'].configure(text=str(val))
                subtotal_lbl.configure(text=t('cart.item.subtotal', subtotal=next((it.subtotal for it in self.controller.shopping_cart.items if it.product.product_id==cart_item.product.product_id), 0)))
                self._update_total()
                
                try:
                    product_page = self.controller.pages.get('ProductPage')
                    if product_page and hasattr(product_page, 'update_cart_display'):
                        product_page.update_cart_display()
                except AttributeError as e:
                    debug(f"ProductPage没有update_cart_display方法: {str(e)}")
                except Exception as e:
                    ErrorHandler.log_exception(e, "更新商品页面购物车显示")
            except ValueError as e:
                messagebox.showwarning("库存不足", str(e))

        # 减少按钮
        decrease_btn = customtkinter.CTkButton(
            qfrm, 
            text='−', 
            width=30, 
            height=25,
            command=decrease
        )
        decrease_btn.pack(side='left', padx=(6, 0))
        
        # 数量标签
        qty_label = customtkinter.CTkLabel(
            qfrm, 
            text=str(qty_val.get()), 
            width=40
        )
        qty_label.pack(side='left', padx=(6, 0))
        qty_label_ref['label'] = qty_label  # 保存引用以便更新
        
        # 增加按钮
        increase_btn = customtkinter.CTkButton(
            qfrm, 
            text='+', 
            width=30, 
            height=25,
            command=increase
        )
        increase_btn.pack(side='left', padx=(6, 0))

        # 立即购买按钮
        buy_btn = customtkinter.CTkButton(
            right, 
            text=t('cart.item.buy_now'), 
            command=lambda ci=cart_item: self._buy_item(ci),
            width=100
        )
        buy_btn.pack(fill='x', pady=(6, 4))
        
        # 移除按钮
        remove_btn = customtkinter.CTkButton(
            right, 
            text=t('cart.item.remove'), 
            command=lambda pid=cart_item.product.product_id: self._remove_item(pid),
            width=100,
            fg_color='#e74c3c',
            hover_color='#c0392b'
        )
        remove_btn.pack(fill='x')

    def _buy_item(self, cart_item):
        # 检查库存
        if not self.controller.product_service.check_stock_availability(
            cart_item.product.product_id, cart_item.quantity
        ):
            messagebox.showerror("库存不足", f"商品 {cart_item.product.name} 库存不足，无法购买")
            return
        
        # 减少库存
        if not self.controller.product_service.update_stock(
            cart_item.product.product_id, -cart_item.quantity
        ):
            messagebox.showerror("购买失败", "库存更新失败，请重试")
            return
        
        # 使用 OrderService 创建订单（直接支付）
        try:
            user_id = self.controller.auth_service.current_user.user_id if self.controller.auth_service.is_logged_in() else "guest"
            order = self.controller.order_service.create_order(
                user_id=user_id,
                cart_items=[cart_item],
                auto_pay=True  # 单个商品购买直接支付
            )
            info(f"✅ 单个商品订单创建成功: {order.order_id}")
        except Exception as e:
            error(f"创建订单失败: {e}")
            messagebox.showerror("购买失败", f"创建订单失败: {e}")
            return
        
        self.controller.shopping_cart.remove_item(cart_item.product.product_id)
        
        # 跳转到订单成功页面
        try:
            # 设置订单成功页面的订单信息
            success_page = self.controller.pages.get('OrderSuccessPage')
            if success_page:
                success_page.set_order(order)
            
            # 跳转到订单成功页面
            self.controller.show_page('OrderSuccessPage')
            info(f"✅ 单个商品购买跳转到订单成功页面: {order.order_id}")
            
        except Exception as e:
            error(f"跳转到订单成功页面失败: {e}")
            # 回退到原来的弹窗方式
            messagebox.showinfo('Purchase', f'Purchased {cart_item.product.name} — thank you!')
            # 如果跳转失败，更新购物车页面
            self.update_data()

    def _remove_item(self, product_id):
        self.controller.shopping_cart.remove_item(product_id)
        self.update_data()

    def _checkout(self):
        # 获取选中的商品
        selected_items = [
            item for item in self.controller.shopping_cart.items
            if item.product.product_id in self.selected_items 
            and self.selected_items[item.product.product_id].get()
        ]
        
        if not selected_items:
            messagebox.showinfo('Checkout', 'Please select at least one item to checkout')
            return
        
        # 计算总价
        total = sum(item.subtotal for item in selected_items)

        # 检查选中商品库存
        for item in selected_items:
            if not self.controller.product_service.check_stock_availability(
                item.product.product_id, item.quantity
            ):
                messagebox.showerror("库存不足", f"商品 {item.product.name} 库存不足，无法结账")
                return

        # 减少库存
        for item in selected_items:
            if not self.controller.product_service.update_stock(
                item.product.product_id, -item.quantity
            ):
                messagebox.showerror("结账失败", f"商品 {item.product.name} 库存更新失败")
                return

        # 使用 OrderService 创建订单（结账时直接支付）
        try:
            user_id = self.controller.auth_service.current_user.user_id if self.controller.auth_service.is_logged_in() else "guest"
            order = self.controller.order_service.create_order(
                user_id=user_id,
                cart_items=selected_items,
                auto_pay=True  # 结账时直接支付
            )
            info(f"✅ 订单创建成功: {order.order_id}")
        except Exception as e:
            error(f"创建订单失败: {e}")
            messagebox.showerror('Order error', f'Failed to save order: {e}')
            return

        # 从购物车移除已结算的商品
        for item in selected_items:
            self.controller.shopping_cart.remove_item(item.product.product_id)
        
        # 跳转到订单成功页面
        try:
            # 设置订单成功页面的订单信息
            success_page = self.controller.pages.get('OrderSuccessPage')
            if success_page:
                success_page.set_order(order)
            
            # 跳转到订单成功页面
            self.controller.show_page('OrderSuccessPage')
            info(f"✅ 跳转到订单成功页面: {order.order_id}")
            
        except Exception as e:
            error(f"跳转到订单成功页面失败: {e}")
            # 回退到原来的弹窗方式
            messagebox.showinfo('Checkout', f'Order placed. Total paid: ¥{total:.2f}')
            # 如果跳转失败，更新购物车页面
            self.update_data()

    def _save_order(self, order):
        dm = DataManager()
        orders_path = os.path.join(dm.data_dir, 'orders.json')
        try:
            if os.path.exists(orders_path):
                with open(orders_path, 'r', encoding='utf-8') as f:
                    data = json.load(f) or []
            else:
                data = []
        except Exception:
            data = []
        data.append(order)
        with open(orders_path, 'w', encoding='utf-8') as f:
            json.dump(data, f, ensure_ascii=False, indent=2)

    def _update_total(self):
        # 只计算选中商品的总价
        total = 0
        for cart_item in self.controller.shopping_cart.items:
            product_id = cart_item.product.product_id
            if product_id in self.selected_items and self.selected_items[product_id].get():
                total += cart_item.subtotal
        self.total_label.configure(text=t('cart.total', total=total))
    
    def _toggle_select_all(self):
        """全选/取消全选"""
        all_selected = self.select_all_var.get()
        for var in self.selected_items.values():
            var.set(all_selected)
        self._update_total()

    def update_data(self):
        # 清除并重新渲染
        for c in self.items_container.winfo_children():
            c.destroy()

        if not self.controller.shopping_cart.items:
            empty_label = customtkinter.CTkLabel(
                self.items_container,
                text=t('cart.empty_message'),
                text_color='gray600'
            )
            empty_label.pack(pady=40)
            self._update_total()
            return
            
        for item in self.controller.shopping_cart.items:
            self._render_item(self.items_container, item)

        self._update_total()
